//
//  ZXCountdownManager.swift
//  ZX
//
//  Created by ZX on 2025/4/27.
//

import Foundation

public typealias ZXCountdownManagerBlock = (_ time: TimeInterval) -> Void

public class ZXCountdownManager {
    
    
    private var timer = Timer()
    public var activeTimeInterval : CGFloat = 1{
        didSet{
            self.timer = self.creatTimer()
        }
    }
    private var finishTimeInterval : TimeInterval = 0
    private var remainingTime : CGFloat{
        let time = CGFloat(self.finishTimeInterval - Date().timeIntervalSince1970)
        return round(time)
    }
    
    public var countdownActive : ZXCountdownManagerBlock?
    public var countdownStar : ZXCountdownManagerBlock?
    public var countdownEnded : ZXCountdownManagerBlock?
    
    public init() {
        timer = self.creatTimer()
    }
    
    public convenience init(countdownActive: ZXCountdownManagerBlock?) {
        self.init()
        self.countdownActive = countdownActive
    }
    
    public func star() {
        self.star(timeInterval: TimeInterval(LONG_MAX) + Date().timeIntervalSince1970)
    }
    public func star(delayTime: TimeInterval) {
        self.star(timeInterval: TimeInterval(delayTime) + Date().timeIntervalSince1970)
    }
    public func star(timeInterval: TimeInterval) {
        finishTimeInterval = timeInterval
        self.starTimer()
        self.countdownStar?(self.remainingTime)
        self.countdownActive?(self.remainingTime)
    }
    
    public func stop() {
        self.timer.invalidate()
        self.countdownEnded?(self.remainingTime)
    }
    
    private func starTimer() {
        DispatchQueue.main.async {[weak self] in
            guard let self = self else { return }
            self.timer.invalidate()
            self.timer = self.creatTimer()
            RunLoop.current.add(self.timer, forMode: .default)
        }
    }
    
    
    private func creatTimer() -> Timer {
        self.timer.invalidate()
        let timer = Timer(timeInterval: self.activeTimeInterval, repeats: true, block: {[weak self] _ in
            guard let weakSelf = self else {
                return
            }
            weakSelf.countdownActive?(weakSelf.remainingTime)
            if weakSelf.remainingTime <= 0{
                weakSelf.stop()
            }
        })
        return timer
    }
}
